/**
 * 代码缺陷管理路由
 *
 * Created by yangyunze on 2021/05/31.
 */
const path = require('path');
const fs = require('fs-extra');
const PhoenixError = require('../../models/phoenix-error');
const middleware = require('./../middleware');
const codeDefects = require('../../models/code-defects');

function createCodeDefect(req, res, next) {
  codeDefects.createCodeDefect(
    req.$project._id,
    req.$projectVersion._id,
    req.$file._id,
    req.params.functionId,
    req.body
  )
    .then((defect) => {
      res.json(codeDefects.getJson(defect));
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

function getCodeDefects(req, res, next) {
  Promise.all([
    codeDefects.getCodeDefects(req.params.functionId, req.query),
    codeDefects.getUnreadTotal(req.params.functionId),
  ])
    .then(([defects, unreadTotal]) => {
      res.json({
        total: defects.length,
        unreadTotal,
        data: defects.map((defect) => codeDefects.getJson(defect)),
      });
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

function getCodeDefect(req, res, next) { // eslint-disable-line no-unused-vars
  res.json(codeDefects.getJson(req.$defect));
}

function deleteCodeDefect(req, res, next) {
  codeDefects.deleteCodeDefect(req.params.defectId)
    .then(() => {
      res.status(204).json();
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

function updateCodeDefect(req, res, next) {
  codeDefects.updateCodeDefect(req.params.defectId, req.body)
    .then((defect) => {
      res.json(defect);
    })
    .catch((err) => {
      next(new PhoenixError(err));
    });
}

function getCodeDefectsOverview(req, res, next) {
  (async () => {
    const ret = await codeDefects.getOverview(req.$projectVersion._id, req.query);
    res.json({
      ...ret,
      version: {
        _id: req.$projectVersion._id,
        versionName: req.$projectVersion.versionName,
        projectName: req.$project.projectName,
      },
    });
  })().catch((err) => {
    next(new PhoenixError(err));
  });
}
function exportCodeDefectsOverview(req, res, next) {
  (async () => {
    const excelName = `${req.$project.projectName}-${req.$projectVersion.versionName}-${req.$locale.__('overview.codeDefect.exportName')}.xlsx`;
    const [xlsxFilePath, cachePath] = await codeDefects.exportCodeDefectsOverview(req.$projectVersion._id, excelName, req.$locale, req.query);
    res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
    res.download(xlsxFilePath, encodeURI(path.basename(xlsxFilePath)), () => fs.remove(cachePath));
  })().catch((err) => {
    next(new PhoenixError(err));
  });
}
/**
 * Export model definition object.
 */
module.exports = (app, prefix) => {
  const codeDefectURL = `${prefix}/code-defects/:defectId.json`;
  const codeDefectsURL = `${prefix}/functions/:functionId/code-defects.json`;
  const codeDefectsOverviewURL = `${prefix}/project-versions/:projectVersionId/code-defects/overview.json`;
  const exportCodeDefectsOverviewURL = `${prefix}/project-versions/:projectVersionId/code-defects/overview.xlsx`;

  // 创建缺陷
  app.post(codeDefectsURL, middleware.user.requireTokenUnexpired);
  app.post(codeDefectsURL, middleware.user.requireAvailable);
  app.post(codeDefectsURL, middleware.user.requireTester);
  app.post(codeDefectsURL, middleware.function.requireFunctionExist);
  app.post(codeDefectsURL, middleware.project.requireProjectAccess);
  app.post(codeDefectsURL, middleware.user.getLockByVersion());
  app.post(codeDefectsURL, createCodeDefect);

  // 获取缺陷列表
  app.get(codeDefectsURL, middleware.user.requireTokenUnexpired);
  app.get(codeDefectsURL, middleware.user.requireAvailable);
  app.get(codeDefectsURL, middleware.user.requireTester);
  app.get(codeDefectsURL, middleware.function.requireFunctionExist);
  app.get(codeDefectsURL, middleware.project.requireProjectAccess);
  app.get(codeDefectsURL, getCodeDefects);

  // 获取单个缺陷
  app.get(codeDefectURL, middleware.user.requireTokenUnexpired);
  app.get(codeDefectURL, middleware.user.requireAvailable);
  app.get(codeDefectURL, middleware.user.requireTester);
  app.get(codeDefectURL, middleware.codeDefect.requireDefectExist);
  app.get(codeDefectURL, middleware.project.requireProjectAccess);
  app.get(codeDefectURL, getCodeDefect);

  // 删除单个缺陷
  app.delete(codeDefectURL, middleware.user.requireTokenUnexpired);
  app.delete(codeDefectURL, middleware.user.requireAvailable);
  app.delete(codeDefectURL, middleware.user.requireTester);
  app.delete(codeDefectURL, middleware.codeDefect.requireDefectExist);
  app.delete(codeDefectURL, middleware.project.requireProjectAccess);
  app.delete(codeDefectURL, middleware.user.getLockByVersion());
  app.delete(codeDefectURL, deleteCodeDefect);

  // 编辑保存单个缺陷
  app.put(codeDefectURL, middleware.user.requireTokenUnexpired);
  app.put(codeDefectURL, middleware.user.requireAvailable);
  app.put(codeDefectURL, middleware.user.requireTester);
  app.put(codeDefectURL, middleware.codeDefect.requireDefectExist);
  app.put(codeDefectURL, middleware.project.requireProjectAccess);
  app.put(codeDefectURL, middleware.user.getLockByVersion());
  app.put(codeDefectURL, updateCodeDefect);

  // 项目总览代码缺陷
  app.get(codeDefectsOverviewURL, middleware.user.requireTokenUnexpired);
  app.get(codeDefectsOverviewURL, middleware.user.requireAvailable);
  app.get(codeDefectsOverviewURL, middleware.user.requireTester);
  app.get(codeDefectsOverviewURL, middleware.projectVersion.requireProjectVersionExist);
  app.get(codeDefectsOverviewURL, getCodeDefectsOverview);

  // 项目总览代码缺陷下载
  app.get(exportCodeDefectsOverviewURL, middleware.user.requireTokenUnexpired);
  app.get(exportCodeDefectsOverviewURL, middleware.user.requireAvailable);
  app.get(exportCodeDefectsOverviewURL, middleware.user.requireTester);
  app.get(exportCodeDefectsOverviewURL, middleware.projectVersion.requireProjectVersionExist);
  app.get(exportCodeDefectsOverviewURL, exportCodeDefectsOverview);
};
